package com.fingard.dsp.bank.directbank.cmb05;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.cmb01.CMB01Base;
import com.fingard.dsp.bank.directbank.cmb01.CMB01Header;
import com.fingard.dsp.bank.helpers.AskNumAmtHelper;
import com.fingard.dsp.bank.helpers.HelperResp;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlReadMode;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import com.google.gson.Gson;
import net.sf.json.JSONArray;

import java.io.File;
import java.sql.Connection;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CMB05BatPayRec extends CMB05Base implements IBatPayRec {
    private static final String INSERTSEQ = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQSEQID,BANKREQSEQID) values (?,?,?,?,?);";
    protected static final String SELECTSEQ = "SELECT BANKREQSEQID FROM REQSEQIDMAPPING WHERE REQSEQID=? AND BANKCODE=?;";

    //1988
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        //暂定198801为正常批量支付
        if ("198801".equals(p_req1988.reqHeader.commandCode)) {
            return d_BatPayRec(p_req1988);
        } else {
            return null;  //代发
        }
    }

    //9188
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
      //  return d_BatPayRec(p_req9188);
    }

    //批量代收和批量代付提交
    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        //返回ATS的对象
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        AskNumAmtHelper askAmtHelper = null;
        try {
            //最大3000笔
            if(Integer.valueOf(p_reqBat.totalNum).intValue()>3000){
                retAts.respCode = "-1";
                retAts.respInfo = "批量支付单次不能大于3000笔";
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = "E9981";
                retAts.writeRetToATS();
                return retAts;
            }
            int i = 0;
            StringBuffer sbf = new StringBuffer();
            CMB05Header bankHeader = new CMB05Header();
            bankHeader.transCode = "DCBPOPER";
            bankHeader.reqSeqID = getQryTransID();
            //组装请求前缀
            writeCommonHeader(sbf,bankHeader);
            //组装请求报文体json
            JSONObject json = new JSONObject();
            HashMap<String,Object> requestMap = new HashMap<String, Object>();
            HashMap<String,String> headMap = new HashMap<String, String>();
            HashMap<String,Object> bodyMap = new HashMap<String, Object>();
            List<Map> detailList = new ArrayList<Map>();
            headMap.put("funcode",bankHeader.transCode);
            headMap.put("userid",bankFront.loginName);
            //	head.put("head",headMap);
            requestMap.put("head",headMap);
            bodyMap.put("modnbr",getBankConfig().getValueAsString("batPay"));//权限模式编码
            while (p_reqBat.readRecord()) {
                i++;
                HashMap<String,String> detailMap = new HashMap<String, String>();
                detailMap.put("refext", p_reqBat.readedDetail.askNumber);
                detailMap.put("sndeac", p_reqBat.readedDetail.payAct);
                detailMap.put("rcveac", p_reqBat.readedDetail.recAct);
                detailMap.put("rcvean", p_reqBat.readedDetail.recName);
                detailMap.put("sysflg", "");
                //对公必须上传收方开户行信息
                if(p_reqBat.readedDetail.isPrivate!=null && p_reqBat.readedDetail.isPrivate.equals("1") && !this.getBankConfig().getValueAsBool("isRecInfo")){
                    bodyMap.put("rcvbrd","");
                    bodyMap.put("rcveab","");
                    bodyMap.put("rcveaa","");
                }else{
                    bodyMap.put("rcvbrd",p_reqBat.readedDetail.cnapsCode);//
                    bodyMap.put("rcveab",p_reqBat.readedDetail.recBankName);//
                    bodyMap.put("rcveaa",p_reqBat.readedDetail.recAreaName);//
                }
                if (p_reqBat.readedDetail.paySpd != null && p_reqBat.readedDetail.paySpd.equals("0")) {
                    detailMap.put("buslvl", "N");
                } else {
                    detailMap.put("buslvl", "Y");
                }
                detailMap.put("ccynbr", "10");//只支持RMB
                detailMap.put("trsamt", p_reqBat.readedDetail.payAmount);
                detailMap.put("nartxt", p_reqBat.readedDetail.memo);//摘要
                detailMap.put("usetxt", p_reqBat.readedDetail.purpose);//用途
                detailList.add(detailMap);
            }
            if(!p_reqBat.totalNum.equals(String.valueOf(i))){
                retAts.respCode = "-1";
                retAts.respInfo = "总笔数和明细笔数不一致";
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = "E9981";
                retAts.writeRetToATS();
                return retAts;
            }
            bodyMap.put("detail",detailList);
            requestMap.put("body",bodyMap);
            json.put("request",requestMap);
            sbf.append(JSON.toJSONString(json));
            String[] tmpStrRet = sendToBank(sbf.toString());
                if (tmpStrRet[0].length() == 0) {
                    //把结果转换成json
                    JSONObject response = JSON.parseObject(tmpStrRet[1]);
                    if (response != null) {
                        String info = response.getString("response");
                        JSONObject content = JSON.parseObject(info);
                        String head = content.getString("head");
                        String body = content.getString("body");
                        Gson gson = new Gson();
                        Map<String, String> headInfo = new HashMap<String, String>();
                        headInfo = gson.fromJson(head, headInfo.getClass());
                        Map<String, String> bodyInfo = new HashMap<String, String>();
                        bodyInfo = gson.fromJson(body, bodyInfo.getClass());
                        if(headInfo!=null){
                            String responseCode = headInfo.get("resultcode");
                            String responseMsg = headInfo.get("resultmsg");
                            if(responseCode!=null && responseCode.equals("SUC0000")) {
                                String bizsts = bodyInfo.get("bizsts");
                                String bathid = bodyInfo.get("bathid");//批次号
                                Connection conn = FGBiz.getLocalDbConn();
                                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                                JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_reqBat.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_reqBat.reqBatchNO, bathid});
                                retAts.reqSeqID = p_reqBat.reqBatchNO;
                                retAts.transState = p_reqBat.reqHeader.commandCode + responseCode;
                                retAts.payInfoCode = bizsts;
                                if(bizsts.equals("A")){
                                    retAts.respCode = "0";
                                    retAts.respInfo = "尚未处理";
                                }else if(bizsts.equals("B")){
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "已撤销";
                                }else if(bizsts.equals("C")){
                                    retAts.respCode = "-2";
                                    retAts.respInfo = "审批拒绝";
                                }else if(bizsts.equals("D")){
                                    retAts.respCode = "0";
                                    retAts.respInfo = "成功";
                                }else if(bizsts.equals("E")){
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "失败";
                                }else if(bizsts.equals("F")){
                                    retAts.respCode = "0";
                                    retAts.respInfo = "部分成功";
                                }else{
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "未知状态";
                                }
                            }else{
                                retAts.respCode = "-1";
                                retAts.respInfo = responseMsg;
                            }
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "请求未正常返回";
                    }
                } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                    retAts.respCode = "0";
                    retAts.respInfo = tmpStrRet[1];
                    retAts.reqSeqID = p_reqBat.reqBatchNO;
                    retAts.transState = PaymentState.FAIL_Batch;
                    retAts.payInfoCode = tmpStrRet[0];
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            FGBiz.limitMsg.exception(reqHeader.bankCode + "." + reqHeader.transType, e);
        } finally {
            if (askAmtHelper != null) {
                askAmtHelper.close();
            }
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_reqBat.reqBatchNO;
        }
        retAts.writeRetToATS();
        return retAts;
    }

    //1998 状态查询
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return d_QryBatPayRec(p_req1998);
    }

    //9198
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }

    //批量代收和批量代付状态查询
    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
        retAts.reqSeqID = p_reqQryBat.reqBatchNO;
        //step1 查批次信息
        String bathid = "";
        //获取流水号
        Connection conn = FGBiz.getLocalDbConn();
        Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, SELECTSEQ, new Object[]{p_reqQryBat.reqBatchNO, p_reqQryBat.reqHeader.bankCode});
        if(selMap.size()>0){
            bathid = selMap.get("BANKREQSEQID").toString();
            WriteBankLogLn("映射核心批次为："+bathid);
        }else{
            retAts.respCode = "-1";
            retAts.respInfo = "根据资金批次号未找到银行返回的批次号";
            retAts.writeAfterDetail();
            WriteBankLogLn("根据资金批次号未找到银行返回的批次号");
            return retAts;
        }
        StringBuffer sbf = new StringBuffer();
        CMB05Header bankHeader = new CMB05Header();
        bankHeader.transCode = "DCBPBQRY";
        bankHeader.reqSeqID = getQryTransID();
        //组装请求前缀
        writeCommonHeader(sbf,bankHeader);
        //组装请求报文体json
        JSONObject json = new JSONObject();
        HashMap<String,Object> requestMap = new HashMap<String, Object>();
        HashMap<String,String> headMap = new HashMap<String, String>();
        HashMap<String,String> bodyMap = new HashMap<String, String>();
        headMap.put("funcode",bankHeader.transCode);
        headMap.put("userid",bankFront.loginName);
        //	head.put("head",headMap);
        requestMap.put("head",headMap);
        bodyMap.put("bgndat",p_reqQryBat.bgnDate.substring(0,10));//开始时间
        bodyMap.put("enddat",Format.Date10Format.format(new Date()));//结束时间
        bodyMap.put("bathid",bathid);//批次号
        requestMap.put("body",bodyMap);
        json.put("request",requestMap);
        sbf.append(JSON.toJSONString(json));
        String[] tmpStrRet = sendToBank(sbf.toString());
        if (tmpStrRet[0].length() == 0) {
            //把结果转换成json
            JSONObject response = JSON.parseObject(tmpStrRet[1]);
            if (response != null) {
                String info = response.getString("response");
                JSONObject content = JSON.parseObject(info);
                String head = content.getString("head");
                String body = content.getString("body");
                Gson gson = new Gson();
                Map<String, String> headInfo = new HashMap<String, String>();
                headInfo = gson.fromJson(head, headInfo.getClass());
                Map<String, String> bodyInfo = new HashMap<String, String>();
                bodyInfo = gson.fromJson(body, bodyInfo.getClass());
                if(headInfo!=null){
                    String responseCode = headInfo.get("resultcode");
                    String responseMsg = headInfo.get("resultmsg");
                    if(responseCode!=null && responseCode.equals("SUC0000")) {
                        //根据状态码判断
                        JSONObject bodyInfos = JSON.parseObject(body);
                        String args = bodyInfos.getString("qryres");
                        JSONArray array = JSONArray.fromObject(args);
                        Map<String, String> recordInfo = new HashMap<String, String>();
                        String record = "";
                        //银行不支持单批次状态查询（遍历集合，找到为止）
                        for(int m = 0;m<array.size();m++){
                            String recordList = array.getString(m);
                            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
                            Matcher mc = p.matcher(recordList);
                            String str = mc.replaceAll("");
                            String repBathid = str.substring(str.indexOf("bathid")+9,str.indexOf("bathid")+25);
                            if(repBathid.equals(bathid)){
                                record = recordList;
                                break;
                            }
                        }
                        if(record.length()==0){
                            retAts.respCode = "-1";
                            retAts.respInfo = "该日期端未获取到本次查询批次号的状态信息";
                            WriteBankLogLn("根据资金批次号未找到银行返回的批次号");
                            return retAts;
                        }
                        recordInfo = gson.fromJson(record, recordInfo.getClass());
                        String bizsts = recordInfo.get("bizsts");
                        retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                        retAts.transState = p_reqQryBat.reqHeader.commandCode + "+" + bizsts;
                        retAts.payInfoCode = bizsts;
                        if(bizsts.equals("A")){
                            retAts.respCode = "2";
                            retAts.respInfo = "尚未处理";
                        }else if(bizsts.equals("B")){
                            retAts.respCode = "-1";
                            retAts.respInfo = "已撤销";
                        }else if(bizsts.equals("C")){
                            retAts.respCode = "-1";
                            retAts.respInfo = "审批拒绝";
                        }else if(bizsts.equals("D")){
                            retAts.respCode = "0";
                            retAts.respInfo = "成功";
                        }else if(bizsts.equals("E")){
                            retAts.respCode = "-1";
                            retAts.respInfo = "失败";
                        }else if(bizsts.equals("F")){
                            retAts.respCode = "0";
                            retAts.respInfo = "部分成功";
                        }else if(bizsts.equals("G")){
                            retAts.respCode = "2";
                            retAts.respInfo = "银行处理中";
                        }
                    }else{
                        retAts.respCode = "-1";
                        retAts.respInfo = responseMsg;
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "请求未正常返回";
            }
        } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
            retAts.respCode = "0";
            retAts.respInfo = tmpStrRet[1];
            retAts.transState = PaymentState.FAIL_Payment;
            retAts.payInfoCode = tmpStrRet[0];
        } else {
            retAts.respCode = "-1";
            retAts.respInfo = tmpStrRet[1];
        }

        //step2查明细(非成功状态直接返回)
        if(!retAts.respCode.equals("0")){
            if(retAts.respCode.equals("2")){
                retAts.respCode = "0";
            }
            return retAts;
        }
        retAts.writeBeforeDetail();
        try {
            JSONObject ctnkey = new JSONObject();//初始值
            ctnkey.put("start","0");
            while (ctnkey!=null) {
                String sbfr = createDetailRequest(bathid, "1000", ctnkey);
                String[] tmpStrRet1 = sendToBank(sbfr);
                if (tmpStrRet1[0].length() == 0) {
                    //把结果转换成json
                    JSONObject response = JSON.parseObject(tmpStrRet1[1]);
                    if (response != null) {
                        String info = response.getString("response");
                        JSONObject content = JSON.parseObject(info);
                        String head = content.getString("head");
                        String body = content.getString("body");
                        Gson gson = new Gson();
                        Map<String, String> headInfo = new HashMap<String, String>();
                        headInfo = gson.fromJson(head, headInfo.getClass());
                        Map<String, String> bodyInfo = new HashMap<String, String>();
                        bodyInfo = gson.fromJson(body, bodyInfo.getClass());
                        if (headInfo != null) {
                            String responseCode = headInfo.get("resultcode");
                            String responseMsg = headInfo.get("resultmsg");
                            if (responseCode != null && responseCode.equals("SUC0000")) {
                                //根据状态码判断
                                JSONObject bodyInfo1 = JSON.parseObject(body);
                                String args = bodyInfo1.getString("detail");
                                JSONArray array = JSONArray.fromObject(args);
                                ctnkey = JSON.parseObject(bodyInfo.get("ctnkey"));
                                for (int m = 0; m < array.size(); m++) {
                                    RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                    String record = array.getString(m);
                                    Map<String, String> recordInfo = new HashMap<String, String>();
                                    recordInfo = gson.fromJson(record, recordInfo.getClass());
                                    tmpRetDetail.bkSeq = recordInfo.get("bseqno");
                                    tmpRetDetail.recAct = recordInfo.get("rcveac");
                                    tmpRetDetail.recName = recordInfo.get("rcvean");
                                    tmpRetDetail.payAct = recordInfo.get("sndeac");
                                    tmpRetDetail.payName = recordInfo.get("sndean");
                                    tmpRetDetail.payAmount = recordInfo.get("trsamt");
                                    tmpRetDetail.result = p_reqQryBat.reqHeader.commandCode + "+" + recordInfo.get("dtlsts");
                                    tmpRetDetail.postScript = recordInfo.get("cltref");
                                    tmpRetDetail.usage = recordInfo.get("usetxt");
                                    tmpRetDetail.memo = recordInfo.get("nartxt");
                                    tmpRetDetail.payInfoCode = recordInfo.get("cannar");
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = responseMsg;
                            }
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "请求未正常返回";
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet1[1];
                }
            }
        } catch (Exception e) {
            FGBiz.limitMsg.exception(this.getLogCode(), e);
            retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
            retAts.reqSeqID = p_reqQryBat.reqBatchNO;
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_reqQryBat.reqBatchNO;
        }
        if (retAts.respCode.equals("-1")) {
            retAts.writeBeforeDetail();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    public String createDetailRequest(String bathid,String pagmax,JSONObject ctnkey){
        StringBuffer sbf = new StringBuffer();
        CMB05Header bankHeader = new CMB05Header();
        bankHeader.transCode = "DCBPDQRY";
        bankHeader.reqSeqID = getQryTransID();
        //组装请求前缀
        writeCommonHeader(sbf,bankHeader);
        //组装请求报文体json
        JSONObject json = new JSONObject();
        HashMap<String,Object> requestMap = new HashMap<String, Object>();
        HashMap<String,String> headMap = new HashMap<String, String>();
        HashMap<String,Object> bodyMap = new HashMap<String, Object>();
        headMap.put("funcode",bankHeader.transCode);
        headMap.put("userid",bankFront.loginName);
        //	head.put("head",headMap);
        requestMap.put("head",headMap);
        bodyMap.put("bathid",bathid);
        bodyMap.put("pagmax",pagmax);
        if(!ctnkey.get("start").toString().equals("0")) {
            bodyMap.put("ctnkey", ctnkey);
        }
        requestMap.put("body",bodyMap);
        json.put("request",requestMap);
        sbf.append(JSON.toJSONString(json));
        return sbf.toString();
    }
}
